<template>
    <div id="uiTabCont" class="ui_tab_cont">
        <table id="uiBigTab" cellspacing="0" cellpadding="0" border="0">
            <thead id="uiThead"></thead>
            <tbody id="uiTbody"></tbody>
        </table>
    </div>
</template>
<script setup>
import { onMounted, defineProps, watch } from 'vue'
const prop = defineProps({
    /**
     * 表格标题
     * {*} String 
     * */ 
    title: {
        default: '表格标题',
        type: String,
    },
    /**
     * 表格head部分，表头
     * { * } 
     * */ 
    tabHead: {
        default: () => ({}),
        type: Object,
        required: true
    },
    /**
     * 表格内容
     * Array数组格式
     * */ 
    tabBody: {
        default: () => ([]),
        type: Array,
        required: true
    }
})
watch(() => prop.tabBody, () => {
    renderTbody()
})
let uiTabCont = null
let UiBigTabHeadEl = null
let UiBigTabBodyEl = null
const tbOption = {
    pageSize: 100,
    pageIndex: 0,
}
tbOption.totalPage = Math.ceil(prop.tabBody / tbOption.pageSize)
let TBodyFragment = document.createDocumentFragment('tbody')
const tbodyFragmentList = []
let isRedenr = true

onMounted(() => {
    uiTabCont = document.getElementById('uiTabCont')
    UiBigTabHeadEl = document.getElementById('uiThead')
    UiBigTabBodyEl = document.getElementById('uiTbody')
    initElment()
    if(prop.tabBody.length) { renderTbody() }
    listenerSrcoll()
})
// 监听表格滚动
const listenerSrcoll = () => {
    uiTabCont.addEventListener('scroll', () => srcollFun())
}
//滚动执行函数
const srcollFun = () => {
    if ((uiTabCont.scrollTop + uiTabCont.clientHeight) > (uiTabCont.scrollHeight - 50)) {
        renderTbody() // 向下滚动正常执行添加列表
    } else if (uiTabCont.scrollTop < 300 && tbodyFragmentList.length && isRedenr) {
        isRedenr = false
        addStoreTbody()  // 向上滚动 添加dom片段
    }
}
// 向上滚动 添加dom片段
const addStoreTbody = () => {
    let flgTag = UiBigTabBodyEl.firstChild
    UiBigTabBodyEl.insertBefore(tbodyFragmentList.pop(), UiBigTabBodyEl.firstChild)
    uiTabCont.scrollTop = flgTag.offsetTop
    let i = tbOption.pageSize
    while(i) {
        UiBigTabBodyEl.removeChild(UiBigTabBodyEl.lastChild)
        i--
    }
    tbOption.pageIndex--
    isRedenr = true
}
// 表格表头渲染
const initElment = () => {
    let tabEl = document.createDocumentFragment('table')
    let tabHeadEl = document.createElement('tr')
    tabHeadEl.setAttribute('class', 'big_tb_th')
    for(let key in prop.tabHead) {
        let tabHeadTdEl = document.createElement('td')
        tabHeadTdEl.setAttribute('class', 'big_tb_tr_td')
        tabHeadTdEl.innerText = `${prop.tabHead[key]}`
        tabHeadEl.appendChild(tabHeadTdEl)
    }
    tabEl.appendChild(tabHeadEl)
    UiBigTabHeadEl.appendChild(tabEl)
}
// 表格内容渲染 预加载 tbOption.pageSize 行
const renderTbody = () => {
    if(tbOption.pageIndex*tbOption.pageSize >= prop.tabBody.length) return
    const timestar = Date.now()
    const tabKeys = Object.keys(prop.tabHead)
    for(let i = 0; i < tbOption.pageSize; i++) {
        let tabBodyEl = document.createElement('tr')
        tabBodyEl.setAttribute('class', 'big_tb_body')
        let tdList = prop.tabBody[i+(tbOption.pageSize*(tbOption.pageIndex))]
        if(!tdList) return
        for(let tabKey of tabKeys) {
            let tabBodyTdEl = document.createElement('td')
            tabBodyTdEl.setAttribute('class', 'big_tb_tr_td')
            tabBodyTdEl.innerText = `${tdList[tabKey]}`
            tabBodyEl.appendChild(tabBodyTdEl)
        }
        TBodyFragment.appendChild(tabBodyEl)
    }
    if((tbOption.pageIndex * tbOption.pageSize) >= 500) { delTbBody() }
    UiBigTabBodyEl.appendChild(TBodyFragment)
    tbOption.pageIndex++
    console.log('表格内容渲染用时：'+(Date.now() - timestar)+'ms');
}
// 删除前面的dom
const delTbBody = () => {
    let TBodyFragmentStore = document.createDocumentFragment()
    var firstContainerChildren = document.querySelectorAll(`#uiTbody > tr:nth-child(-n+${tbOption.pageSize})`);
    let i = 0
    while(firstContainerChildren[i]) {
        TBodyFragmentStore.appendChild(firstContainerChildren[i])
        i++
    }
    tbodyFragmentList.push(TBodyFragmentStore)
}
</script>
<style lang="css" scoped>
.ui_tab_cont{
    max-height: 500px;
    width: 100%;
    overflow: auto;
    display: inline-block;
    border: 1px solid #ebeef5;
    border-left: none;
    border-right: none;
}
</style>